//
//  TPPermissionMicrophoneTools.m
//  Pods
//
//  Created by caixun on 2016/12/24.
//
//


#import "MPTAuthorizationMicrophoneTools.h"
#import <AVFoundation/AVFoundation.h>


#define MPTAskedForMicrophonePermission @"MPTAskedForMicrophonePermission"


@interface MPTAuthorizationMicrophoneTools ()
{
    AuthorizationHandler _completion;
}


@end


@implementation MPTAuthorizationMicrophoneTools


+ (instancetype)sharedInstance
{
    static MPTAuthorizationMicrophoneTools *_instance = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        _instance = [[MPTAuthorizationMicrophoneTools alloc] init];
    });
    
    return _instance;
}


#pragma mark - Microphone

- (MPE_AuthorizationStatus)authorizationStatus
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    if ([audioSession respondsToSelector:@selector(recordPermission)])
    {
        AVAudioSessionRecordPermission permission = [[AVAudioSession sharedInstance] recordPermission];
        switch (permission)
        {
            case AVAudioSessionRecordPermissionGranted:
                return MPE_AuthorizationAuthorized;
            case AVAudioSessionRecordPermissionDenied:
                return MPE_AuthorizationDenied;
            case AVAudioSessionRecordPermissionUndetermined:
                return MPE_AuthorizationNotDetermined;
        }
    }
    else
    {
        bool previouslyAsked =
        [[NSUserDefaults standardUserDefaults] boolForKey:MPTAskedForMicrophonePermission];
        if (previouslyAsked)
        {
            dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            __block BOOL hasAccess;
            [audioSession requestRecordPermission:^(BOOL granted)
            {
                hasAccess = granted;
                dispatch_semaphore_signal(sema);
            }];
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
            
            return (hasAccess) ? MPE_AuthorizationAuthorized : MPE_AuthorizationDenied;
        }
        else
        {
            return MPE_AuthorizationDenied;
        }
    }
}

- (void)authorize:(AuthorizationHandler)completion
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    if ([audioSession respondsToSelector:@selector(recordPermission)])
    {
        AVAudioSessionRecordPermission permission = [audioSession recordPermission];
        switch (permission)
        {
            case AVAudioSessionRecordPermissionGranted:
            {
                if (completion)
                {
                    completion(MPE_AuthorizationAuthorized, nil);
                }
            }
                break;
            case AVAudioSessionRecordPermissionDenied:
            {
                if (completion)
                {
                    completion(MPE_AuthorizationDenied, nil);
                }
            }
                break;
            case AVAudioSessionRecordPermissionUndetermined:
            {
                _completion = completion;
                [self actuallyAuthorize];
            }
                break;
        }
    }
    else
    {
        [audioSession requestRecordPermission:^(BOOL granted)
        {
            [[NSUserDefaults standardUserDefaults] setBool:true forKey:MPTAskedForMicrophonePermission];
            [[NSUserDefaults standardUserDefaults] synchronize];
            if (completion)
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (granted)
                    {
                        completion(MPE_AuthorizationAuthorized, nil);
                    }
                    else
                    {
                        completion(MPE_AuthorizationDenied, nil);
                    }
                });
            }
        }];
    }
}

- (MPE_AuthorizationType)permissionType
{
    return MPE_AuthorizationMicrophone;
}

- (void)actuallyAuthorize
{
    AVAudioSession *session = [[AVAudioSession alloc] init];
    NSError *error;
    [session setCategory:@"AVAudioSessionCategoryPlayAndRecord" error:&error];
    [session requestRecordPermission:^(BOOL granted)
     {
        if (_completion)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (granted)
                {
                    _completion(MPE_AuthorizationAuthorized, nil);
                }
                else
                {
                    _completion(MPE_AuthorizationDenied, nil);
                }
            });
        }
    }];
}

- (void)canceledAuthorization:(NSError *)error
{
    if (_completion)
    {
        _completion(MPE_AuthorizationDenied, error);
    }
}


@end
